<template>
  <div class="main-todo">
    <div class="main-todo-header">
      <input
        type="checkbox"
        id="toggle-all"
        class="toggle-all"
        @change="toggleAllTodo"
      />
      <label
        for="toggle-all"
        :class="['toggle-all-label', toggleAllCompleted == 0 ? 'checked' : '']"
        >﹀</label
      >
      <!-- autofocus可以在input输入框中实现自动聚焦 -->
      <input
        v-model="content"
        @keyup.enter="handleAdd"
        class="add-todo"
        type="text"
        placeholder="What to do ? ↵"
        autofocus
      />
    </div>

    <todo-item
      v-for="todo in filterTodos"
      @fulfill="checkChange"
      @update="updateLabel"
      @del="deleteLabel"
      :key="todo.id"
      :todoItem="todo"
    ></todo-item>
    <todo-info
      :total="total"
      @alter="alterInfo"
      @clear="clearCompleted"
    ></todo-info>
  </div>
</template>

<script>
import TodoItem from "./coms/TodoItem.vue";
import TodoInfo from "./coms/TodoInfo.vue";
export default {
  name: "MainTodo",
  components: {
    TodoInfo,
    TodoItem,
  },
  data() {
    return {
      todos: [],
      // 存储输入框中的内容
      content: "",
      filterTodos: [],
      state: "all",
      // 控制数据存储方式
      storageSelecter: false,
    };
  },

  computed: {
    total() {
      return this.filterTodos.filter((item) => item.completed == 0).length;
    },
    // 表示处于待办状态(即completed=0)的项目的数量
    activeNumber() {
      return this.todos.filter((item) => item.completed == 0).length;
    },
    // 表示全部项目是否处于选中状态(0全选，1未全选)
    toggleAllCompleted() {
      if (this.activeNumber == 0) {
        return 0;
      } else {
        return 1;
      }
    },
  },
  watch: {
    todos: {
      deep: true,
      handler(value) {
        console.log("...侦听器工作了");
        localStorage.setItem("todos", JSON.stringify(value));
      },
    },
  },
  // 实现数据初始化
  created() {
    if (this.storageSelecter) {
      // 发送ajax请求
      this.getAll();
    } else {
      // 从浏览器中读取数据
      let value = JSON.parse(localStorage.getItem("todos"));

      if (value === null) {
        //如果浏览器中没有存储todos这项数据
        // 那我们就自己来完成todos数组与filterTodos数组的数据初始化
        this.todos = [];
        this.filterTodos = this.todos;
      } else {
        // 如果浏览器中有存储todos这项数据
        // 就利用下载的数据value，来完成todos数组与filterTodos数组的数据初始化
        this.todos = value;
        this.filterTodos = this.todos;
      }
    }
  },

  methods: {
    getAll() {
      this.$http.get("http://localhost:3000/todos").then((res) => {
        // 结构res.data
        const { code, message, result } = res.data;
        if (code == 0) {
          this.todos = result;
          this.updateFilterTodos();
        }
      });
    },

    // 添加项目
    handleAdd() {
      // 弹窗提示
      if (this.content == "") {
        alert("您还没有输入内容呢！");
        return;
      }
      if (this.storageSelecter == true) {
        // 发送post请求
        this.$http
          .post("http://localhost:3000/todos", { content: this.content })
          .then((res) => {
            // 重新渲染页面
            this.getAll();
          });
      } else {
        this.todos.push({
          id: this.uuid(),
          content: this.content,
          completed: 0,
        });
      }
      // 清空输入框
      this.content = "";
      // console.log(this.filterTodos);
    },

    // 实现复选框逻辑，更新项目的completed属性
    checkChange(id) {
      // 拿到被点击的那个todoItem
      const data = this.todos.filter((item) => item.id == id);
      // 修改todo项目的completed属性
      data[0].completed == 1
        ? (data[0].completed = 0)
        : (data[0].completed = 1);
      if (this.storageSelecter) {
        this.$http
          .put("http://localhost:3000/todos/" + id, data[0])
          .then((res) => {
            const { code, message, result } = res.data;
            if (code == 0) {
              this.getAll();
            }
          });
      }
    },
    // 更新项目的内容
    updateLabel(id, content) {
      // 拿到被点击的那个todoItem
      const data = this.todos.filter((item) => item.id == id);
      data[0].content = content;
      this.$http
        .put("http://localhost:3000/todos/" + id, data[0])
        .then((res) => {
          const { code, message, result } = res.data;
          if (code == 0) {
            this.getAll();
          }
        });
    },

    // 删除项目
    deleteLabel(id) {
      if (this.storageSelecter) {
        this.$http.delete("http://localhost:3000/todos/" + id).then((res) => {
          const { code, message, result } = res.data;
          if (code == 0) {
            this.getAll();
          }
        });
      } else {
        this.todos = this.todos.filter((item) => item.id != id);
        this.updateFilterTodos();
      }
    },

    alterInfo(text) {
      this.state = text;
      this.updateFilterTodos();
    },
    updateFilterTodos() {
      // 更新filterTodos的值
      switch (this.state) {
        case "all":
          this.filterTodos = this.todos;
          break;
        case "active":
          this.filterTodos = this.todos.filter((item) => item.completed == 0);
          break;
        case "completed":
          this.filterTodos = this.todos.filter((item) => item.completed == 1);
          break;
        default:
          this.filterTodos = this.todos;
      }
    },

    // 清除所有已完成的项目
    clearCompleted() {
      if (this.storageSelecter) {
        // DELETE /todos?completed=1
        this.$http
          .delete("http://localhost:3000/todos?completed=1")
          .then((res) => {
            const { code, message, result } = res.data;
            if (code == 0) {
              this.getAll();
            }
          });
      } else {
        this.todos = this.todos.filter((item) => item.completed == 0);
        // 实现页面的重新渲染
        this.updateFilterTodos();
      }
    },

    // 实现全选按钮的逻辑
    toggleAllTodo() {
      if (this.storageSelecter) {
        // 发送请求
        this.$http({
          method: "put",
          url: "http://localhost:3000/todos",
          params: {
            completed: this.toggleAllCompleted,
          },
        }).then((res) => {
          const { code, message, result } = res.data;
          if (code == 0) {
            this.getAll();
          }
        });
      } else {
        /*
          错误方法:无论是使用循环遍历还是过滤都不行
            for (let todo of this.todos) {
              todo.completed = this.toggleAllCompleted;
              console.log(this.toggleAllCompleted);
            }

            const arr = this.todos.filter(
              (item) => item.completed != this.toggleAllCompleted
            );
            for (let item of arr) {
              item.completed = this.toggleAllCompleted;
            }
        */

        // 对todos数组进行深拷贝，得到新数组newTodos
        const newTodos = JSON.parse(JSON.stringify(this.todos));
        // 遍历newTodos数组，修改元素的completed属性
        for (let todo of newTodos) {
          todo.completed = this.toggleAllCompleted;
        }
        // 更新todos数组
        this.todos = newTodos;
        // 实现页面的重新渲染
        this.updateFilterTodos();
      }
    },

    // 生成uuid
    uuid() {
      return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
        /[xy]/g,
        function (c) {
          var r = (Math.random() * 16) | 0,
            v = c == "x" ? r : (r & 0x3) | 0x8;
          return v.toString(16);
        }
      );
    },
  },
};
</script>

<style lang="stylus">
  @import '~styles/theme.styl'
  @import '~styles/typeface.styl'
.main-todo
  // 相对定位
  position relative
  width 800px
  margin 0 auto

  // background-color rgba(255,255,0,.5)
  border-radius: 5px
  box-shadow: 3px 3px 5px #333
  .toggle-all
    display: none
  .toggle-all-label
    // 绝对定位
    position:absolute
    top 21px
    left 12px
    font-size: 24px
    cursor pointer
    /* &::after
      content: '﹀'
      font-size: 24px
      cursor pointer */
  .checked
    color: $yellow
  .add-todo
    width 100%
    padding : 16px 16px 16px 55px

    margin-bottom: 5px
    background-color rgba(0,0,0,.5)
    // 浏览器有自带的字体，所有如果你没有手动设置字体的话，输入框中字体的粗细就调整不了
    font-size: 24px
    font-family: inherit
    font-weight: 200
    color: $yellow
    
    outline: none
    border: none
    box-sizing:border-box;
    border-radius: 5px 5px 0 0
    &::placeholder
      color: rgba(249, 205, 173,.5)
      font-family: $xh
      font-weight:200
</style>
